home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1997 December / MACPOWER-1997-12.ISO.7z / MACPOWER-1997-12.ISO / AMUG / PROGRAMMING / Raven 1.2.sit / Raven 1.2 / Source / Foundation / OS / ZOSQueue.h < prev    next >
Text File  |  1997-02-01  |  4KB  |  149 lines

  1. /*
  2.  *  File:       ZOSQueue.h
  3.  *  Summary:       Wrappers for interrupt safe OS queues.
  4.  *  Written by: Jesse Jones
  5.  *
  6.  *    Usage:        A TOSQueue can be used whenever you need to use something like an STL 
  7.  *                list at interrupt time. The template type you can use with TOSQueue
  8.  *                is restricted to types that can be implicitly converted to a QElem*.
  9.  *                Typically this is done by mixing MOSElement into the object you want
  10.  *                to place in the queue. For example, TSoundCommand maintains an interrupt
  11.  *                safe list of commands that have been executed:
  12.  *
  13.  *                    class TSoundCommand : public MOSElement {
  14.  *                        ...
  15.  *                    };
  16.  *
  17.  *                    typedef TOSQueue<TSoundCommand*> ZSoundQueue;
  18.  *                    static ZSoundQueue sCompletedCommands;
  19.  *
  20.  *                At this point you can use a subset of the STL list API to operate on
  21.  *                the queue.
  22.  *
  23.  *  Copyright ゥ 1996 Jesse Jones. 
  24.  *    For conditions of distribution and use, see copyright notice in ZTypes.h  
  25.  *
  26.  *  Change History (most recent first):    
  27.  *
  28.  *         <->    11/10/96    JDJ        Created
  29.  */
  30.  
  31. #pragma once
  32.  
  33. #include <Iterator.h>
  34. #include <OSUtils.h>
  35.  
  36. #include <ZDebug.h>
  37.  
  38.  
  39. #pragma profile off                
  40.  
  41. // ===================================================================================
  42. //    class MOSElement
  43. //        A mixin that allows object pointers to be placed in an OS Queue. Derived classes
  44. //        *must* inherit from MOSElement first to ensure QElem is placed first in the object.
  45. // ===================================================================================
  46. class MOSElement : public QElem {
  47.  
  48. //-----------------------------------
  49. //    Initialization/Destruction
  50. //
  51. public:
  52.     virtual                ~MOSElement()                        {}
  53.     
  54.                         MOSElement()                        {qLink = nil; qType = 0;}
  55.                         
  56. private:
  57.                         MOSElement(const MOSElement& rhs);
  58.                         
  59.             MOSElement&    operator=(const MOSElement& rhs);
  60. };
  61.  
  62.  
  63. // ===================================================================================
  64. //    class TOSQueue
  65. //        T should be a pointer to a subclass of QElem (eg something descending from MOSElement).
  66. // ===================================================================================
  67. template <class T>
  68. class TOSQueue : public QHdr {
  69.  
  70. //-----------------------------------
  71. //    Types
  72. //
  73. public:
  74.     typedef T             value_type;
  75.     typedef T&             reference;
  76.     typedef const T&     const_reference;        // const pointer, not const data
  77.     typedef size_t        size_type;
  78.     typedef ptrdiff_t    difference_type;
  79.  
  80. //-----------------------------------
  81. //    Initialization/Destruction
  82. //
  83. public:
  84.                         ~TOSQueue()                            {SAFE_ASSERT(qHead == nil); SAFE_ASSERT(qTail == nil);}
  85.     
  86.                         TOSQueue()                            {qFlags = 0; qHead = qTail = nil;}
  87.                         
  88. private:
  89.                         TOSQueue(const TOSQueue& rhs);
  90.                         
  91.             TOSQueue&    operator=(const TOSQueue& rhs);
  92.  
  93. //-----------------------------------
  94. //    Iterator
  95. //
  96. public:
  97.     class const_iterator : public bidirectional_iterator<T, difference_type> {
  98.     
  99.     public:
  100.                         const_iterator(QElem* element = nil)        {mElement = (T) element;}
  101.  
  102.         bool             operator==(const const_iterator& rhs) const    {return mElement == rhs.mElement;}
  103.         const_reference    operator*() const                            {return mElement;}
  104.         const_iterator& operator++()                                {if (mElement != nil) mElement = (T) mElement->qLink; return *this;}
  105.         const_iterator     operator++(int)                                {const_iterator temp = *this; ++*this; return temp;}
  106.         
  107.     private:
  108.         T    mElement;
  109.     };
  110.  
  111. //-----------------------------------
  112. //    API
  113. //
  114. public:
  115.             const_iterator     begin() const                    {return qHead;}
  116.             const_iterator     end() const                        {return nil;}
  117.             bool             empty() const                    {return qHead == nil;}
  118.             const_reference front() const                    {return (T&) qHead;}
  119.             const_reference back() const                    {return (T&) qTail;}
  120.             void             push_back(T x)                    {Enqueue(x, this);}
  121.             OSErr             erase(const_iterator position)    {return Dequeue(*position, this);}
  122.             OSErr             pop_front()                        {return Dequeue(qHead, this);}
  123.             OSErr             pop_back()                        {return Dequeue(qTail, this);}
  124.             OSErr             remove(T x)                        {return Dequeue(x, this);}
  125.  
  126.             OSErr             splice(TOSQueue& x);
  127. };
  128.  
  129.  
  130. template <class T>
  131. OSErr TOSQueue<T>::splice(TOSQueue& x) 
  132. {
  133.     OSErr err = noErr;
  134.     
  135.     while (err == noErr && !x.empty()) {
  136.         value_type elem = x.front();
  137.         err = x.pop_front();
  138.         
  139.         if (err == noErr)
  140.             this->push_back(elem);
  141.     }
  142.     
  143.     return err;
  144.         
  145. }
  146.  
  147. #pragma profile reset                
  148.  
  149.